﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Core
{
    public class FunHelper
    {
        public static void Try(Action action, Action errhander = null)
        {
            try
            {
                action();
            }
            catch (Exception ex)
            {
                if (errhander is Action) errhander();
                Log.errorlog(ex);
            }
        }
        public static void Try<T>(Func<T> action, Action<T> callback = null, Action errhander = null)
        {
            try
            {
                T t = action();
                if (callback != null)
                    callback(t);
            }
            catch (Exception ex)
            {
                if (errhander is Action) errhander();
                Log.errorlog(ex);
            }
        }
        public static void TryAsync<T>(Func<T> func, Action<T> callback = null, Action errhander = null)
        {
            var task = Task.Factory.StartNew(func);
            if (callback != null)
            {
                task.GetAwaiter().OnCompleted(() =>
                {
                    callback(task.Result);
                });
            }
            task.ContinueWith(_task =>
            {
                if (errhander != null) errhander();
                Log.errorlog(_task.Exception.GetBaseException());
            }, TaskContinuationOptions.OnlyOnFaulted);
        }
        public static void TryAsync(Action<object> action, object state, Action<object> callback = null, object backstate = null, Action<object> errhander = null, object errstate = null)
        {
            var task = Task.Factory.StartNew(action, state);
            if (callback != null)
            {
                task.GetAwaiter().OnCompleted(() =>
                {
                    callback(backstate);
                });
            }
            task.ContinueWith(_task =>
            {
                if (errhander != null) errhander(errstate);
                Log.errorlog(_task.Exception.GetBaseException());
            }, TaskContinuationOptions.OnlyOnFaulted);
        }

        #region Lambda表达式不动点递归
        public static Func<T, TResult> Fix<T, TResult>(Func<Func<T, TResult>, Func<T, TResult>> f)
        {
            return x => f(Fix(f))(x);
        }
        public static Func<T1, T2, TResult> Fix<T1, T2, TResult>(Func<Func<T1, T2, TResult>, Func<T1, T2, TResult>> f)
        {
            return (x, y) => f(Fix(f))(x, y);
        }
        public static Func<T1, T2, T3, TResult> Fix<T1, T2, T3, TResult>(Func<Func<T1, T2, T3, TResult>, Func<T1, T2, T3, TResult>> f)
        {
            return (x, y, z) => f(Fix(f))(x, y, z);
        }
        #endregion
    }
}
